/*****************************************************
*                                                                          
*               COPYRIGHT (c) 2015-2017 Hargic Corporation              
*                         All Rights Reserved                              
*                                                                          
* The source code contained or described herein and all documents          
* related to the source code ("Material") are owned by Hargic         
* Corporation or its licensors.  Title to the Material remains             
* with Hargic Corporation or its suppliers and licensors.               
*                                                                          
* The Material is protected by worldwide copyright and trade secret        
* laws and treaty provisions. No part of the Material may be used,         
* copied, reproduced, modified, published, uploaded, posted, transmitted,  
* distributed, or disclosed in any way except in accordance with the       
* applicable license agreement.                                            
*                                                                          
* No license under any patent, copyright, trade secret or other            
* intellectual property right is granted to or conferred upon you by       
* disclosure or delivery of the Materials, either expressly, by            
* implication, inducement, estoppel, except in accordance with the         
* applicable license agreement.                                            
*                                                                          
* Unless otherwise agreed by Hargic in writing, you may not remove or   
* alter this notice or any other notice embedded in Materials by Hargic 
* or Hargic's suppliers or licensors in any way.                        
*                                                                          
** Author: ted.huang
** Date: 2018-02-25
*
*****************************************************/

/***** Include files ********************************/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <bcm2835.h>
#include "spi_if.h"
#include "rc522.h"

/***** Defines **************************************/

#define RC522_RESET_PIN         24
#define RC522_CSN_PIN           25

#define IC_CARD_PATH        "/home/pi/workspace/iccard/ic_card.txt"

/***** Define structure *****************************/

/***** Define constant ******************************/

/***** Define global ********************************/

/***** Define Prototype of functions ****************/

static int rc522_gpio_init(void)
{
    if (!bcm2835_init())
    {
        printf("bcm2835_init failed. Are you running as root??\n");
        return -1;
    }

    bcm2835_gpio_fsel(RC522_CSN_PIN, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RC522_RESET_PIN, BCM2835_GPIO_FSEL_OUTP);
    return 0;
}

static unsigned char rc522_spi_transfer(unsigned char val)
{
    return spi_transfer(val);
}

static void rc522_spi_csn(unsigned char level)
{
    if (level == RC522_SPI_CSN_LEVEL_LOW)
        bcm2835_gpio_write(RC522_CSN_PIN, LOW);
    else
        bcm2835_gpio_write(RC522_CSN_PIN, HIGH);
}

static void rc522_gpio_reset(unsigned char val)
{
    if (val == RC522_RESET_GPIO_LEVEL_LOW)
        bcm2835_gpio_write(RC522_RESET_PIN, LOW);
    else
        bcm2835_gpio_write(RC522_RESET_PIN, HIGH);
}

static void rc522_delay_ms(unsigned int ms)
{
    bcm2835_delay(ms);
}

static void dump_hex(char *str, unsigned char *buff, unsigned int len)
{
    printf("%s hex %d len:", str, len);
    for(int idx = 0; idx < len; idx++)
    {
        if ((idx % 16) == 0)
            printf("\r\n%p:", &buff[idx]);
        
        printf(" %02x", buff[idx]);
    }
    printf("\r\n");
}

static void rc522_init(void)
{
    PcdReset();
    PcdAntennaOff(); 
    PcdAntennaOn();  
    M500PcdConfigISOType('A');
}

static void createfile(int value)
{
    int ret;
    FILE *fd;   
    char filename[] = IC_CARD_PATH;      //保存在工程目录下

    fd = fopen(filename, "w+");

    ret = fputc('1', fd);
    // printf("%s: fputc ret %d\n", __func__, ret);
    
    fclose(fd);
}

static int check_ic_card_valid(unsigned int id)
{
    const unsigned int valid_group[] = {0xbeb3f5c8, 0xbedb15b0};
    int i;

    printf("%s: enter id 0x%x\n", __func__, id);

    for (i = 0; i < sizeof(valid_group); ++i) {
        printf("%s: valid_group[%d] 0x%x\n", __func__, i, valid_group[i]);
        if (id == valid_group[i])
            return !0;
    }
    return 0;
}

/**
 * @brief
 * @param  None
 * @retval None
 */
int main(int argc, char **argv)
{
	rc522_func_t func;
    unsigned char recv_buff[128];
    unsigned int *ic_card_id;
    int i;

    if (rc522_gpio_init() != 0)
    {
        printf("gpio init failed\n");
        return -1;
    }

	if (spi_init(BCM2835_SPI_BIT_ORDER_MSBFIRST, BCM2835_SPI_MODE0, BCM2835_SPI_CLOCK_DIVIDER_4096) != 0)
    {
		printf("spi init failed.\n");
		return -1;
    }

    printf("%s: system init done\n", __func__);

    func.spi_transfer_byte  = rc522_spi_transfer;
    func.spi_csn_level      = rc522_spi_csn;
    func.gpio_reset         = rc522_gpio_reset;
    func.delay_ms           = rc522_delay_ms;
    rc522_register_spi_func(&func);

    rc522_init();
    printf("%s: rc522 init done\n", __func__);

    // int ret = check_ic_card_valid(0xbeb3f5c8);
    // printf("%s: check_ic_card_valid ret %d\n", __func__, ret);

    // int cnt = 1000;
    while (1) {
        for (i=0; i<2; i++)
            recv_buff[i] = 0x00;

        PcdRequest(0x52, recv_buff);
        // dump_hex("PcdRequest recv", recv_buff, 2);

        for (i=0; i<4; i++)
            recv_buff[i] = 0x00;

        PcdAnticoll(recv_buff);
        
        if (recv_buff[0] != 0x00) {
            // dump_hex("PcdAnticoll recv", recv_buff, 4);

            ic_card_id = (unsigned int *)recv_buff;
            // printf("0x%08x\n", ic_card_id);
            // printf("%s: cnt %d\n", __func__, cnt);

            if (check_ic_card_valid(ic_card_id))
                createfile(1);
        }

        bcm2835_delay(200);
    }

    spi_deinit();
    return 0;
}


/* End of file */



